<template>
  <div class="flex-row">
    <div class="script-box" v-loading="fullscreenLoading">
      <el-descriptions :colon="false" title="采集规则管理" size="medium">
      </el-descriptions>
      <div class="select-box">
        <el-select
          v-model="selectValue"
          @change="getScriptTree"
          style="width: 7vw"
          placeholder="选择状态"
        >
          <el-option
            v-for="item in stateTypeOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          >
          </el-option>
        </el-select>
        <el-input
          v-model="filterText"
          ref="myInput"
          placeholder="输入关键字搜索"
          suffix-icon="el-icon-search"
          style="width: 10vw"
        ></el-input>
      </div>
      <div class="checkbox">
        <el-checkbox
          v-model="allChecked"
          @change="allSelect"
          :indeterminate="isIndeterminate"
          >全选</el-checkbox
        >
        <el-button class="publish" @click="bulkPublishing" type="text"
          >批量发布</el-button
        >
      </div>
      <el-tree
        id="my-model"
        class="tree-flex-col"
        show-checkbox
        :data="treeData"
        :props="props"
        :accordion="true"
        node-key="Guid"
        :highlight-current="true"
        @node-contextmenu="onContextmenu"
        @current-change="clickNode"
        @node-expand="clickNode"
        :filter-node-method="filterNode"
        :default-expanded-keys="expandedKey"
        @check-change="handleCheckChange"
        ref="tree"
      >
        <span class="custom-tree-node" slot-scope="{ node, data }">
          <div style="display: flex; align-items: center">
            <i style="margin-right: 7px" :class="titleIcon(data)"></i>
            <div
              style="display: flex"
              v-if="node.label.indexOf(filterText) > -1"
            >
              {{ node.label.substr(0, node.label.indexOf(filterText)) }}
              <span style="color: #f50">{{ filterText }}</span>
              {{
                node.label.substr(
                  node.label.indexOf(filterText) + filterText.length
                )
              }}
            </div>
            <span v-else>{{ node.label }}</span>
          </div>
        </span>
        <!-- <span class="custom-tree-node" slot-scope="{ node, data }">
          <div>
            <i style="margin-right: 7px" :class="titleIcon(data)"></i>
            <span>{{ node.label }}</span>
          </div>

        </span> -->
      </el-tree>
    </div>
    <div class="script-main">
      <el-card class="flex-col">
        <div class="title">
          <span v-text="versionSpan" v-show="buttonShow"></span>
          <span v-text="ruleNameSpan" v-show="buttonShow"></span>
          <div>
            <el-button
              size="mini"
              type="primary"
              @click="saveScript"
              v-show="buttonShow"
              >保存</el-button
            >
            <el-button
              size="mini"
              type="primary"
              @click="
                () => {
                  templateAddOrEditDialogVisible = true;
                }
              "
              v-show="buttonShow"
              >另存为模板</el-button
            >
            <el-button
              type="mini"
              @click="publishContent"
              :disabled="!isPublish"
              v-show="buttonShow"
              >发布</el-button
            >
            <!-- <el-button
              v-show="!isPublish"
              size="mini"
              @click="cancelPublishContent"
              >取消发布</el-button
            > -->
          </div>
        </div>
        <div class="divider"></div>
        <div class="flex-row" style="align-items: center">
          <iframe
            v-if="editable"
            class="iframe"
            id="mainiframe"
            src="/idehtml/edit.html"
          ></iframe>
          <el-button
            v-show="buttonShow"
            class="modelbtn"
            :icon="modelBtnIcon"
            @click="startCodeModel"
          ></el-button>

          <transition name="fade">
            <div v-show="drawer" class="drawer" v-loading="templateLoading">
              <el-descriptions :colon="false" title="模板库" size="small">
              </el-descriptions>
              <el-input
                placeholder="搜索模板"
                v-model="modefilterText"
                suffix-icon="el-icon-search"
              >
              </el-input>
              <el-tree
                @node-click="getCurrentModel"
                class="model-tree"
                node-key="Id"
                :data="modelData"
                :props="modelProps"
                :highlight-current="true"
                default-expand-all
                :filter-node-method="filterCodeMod"
                ref="codeModelTree"
              >
                <span class="custom-tree-node" slot-scope="{ node, data }">
                  <el-tooltip
                    :disabled="data.ParentId == 0"
                    class="item"
                    effect="light"
                    placement="left-end"
                  >
                    <div slot="content" v-show="data.ParentId != 0">
                      模板：{{ data.TemplateName }}<br />说明：{{
                        data.Description
                      }}
                    </div>
                    <div class="span-div" draggable="true">
                      <div>
                        <span
                          v-show="data.ParentId != 0"
                          class="blue-square"
                        ></span>
                        <span>{{ node.label }}</span>
                      </div>
                      <span
                        v-show="data.ParentId != 0 && data.Id == modeNodeKey"
                      >
                        <el-button
                          type="text"
                          size="mini"
                          @click="() => codePreview(node, data)"
                        >
                          预览
                        </el-button>
                        <el-button
                          type="text"
                          size="mini"
                          @click="() => codeInsert(node, data)"
                        >
                          插入
                        </el-button>
                      </span>
                    </div>
                  </el-tooltip>
                </span>
              </el-tree>
            </div>
          </transition>
        </div>
      </el-card>
    </div>

    <el-dialog
      :visible.sync="dialogVisible"
      width="30%"
      @close="
        () => {
          dialogVisible = false;
          this.$refs['cycleSettingForm'].clearValidate();
        }
      "
    >
      <span slot="title" style="text-align: center"
        >循环设置
        <el-divider></el-divider>
      </span>
      <el-form
        label-width="200px"
        autocomplete="off"
        ref="cycleSettingForm"
        :model="cycleSettingForm"
      >
        <el-form-item
          v-show="timeModel"
          label="循环间隔时间(ms)："
          prop="interval"
          :rules="[
            { required: true, message: '时间间隔不能为空', trigger: 'blur' },
            { pattern: /^[1-9]\d*$/, message: '请输入正整数' },
          ]"
        >
          <el-input
            v-model="cycleSettingForm.interval"
            style="width: 50%"
            placeholder="请输入间隔时间值"
            autocomplete="off"
          ></el-input>
          <span> *100</span>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer" style="text-align: center">
        <el-divider></el-divider>
        <div>
          <el-button
            @click="
              () => {
                dialogVisible = false;
                this.$refs['cycleSettingForm'].clearValidate();
              }
            "
            >取 消</el-button
          >
          <el-button type="primary" @click="changeInterval('cycleSettingForm')"
            >确 定</el-button
          >
        </div>
      </span>
    </el-dialog>

    <el-dialog
      :visible.sync="renameVisible"
      width="30%"
      @close="
        () => {
          (renameVisible = false), (this.newScriptName = '');
        }
      "
    >
      <span slot="title" style="text-align: center"
        >重命名
        <el-divider></el-divider>
      </span>
      <el-form label-width="200px">
        <el-form-item label="旧脚本名：">
          <el-input
            v-model="seletNode.DisplayName"
            style="width: 50%"
            disabled
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="新脚本名：">
          <el-input
            style="width: 50%"
            placeholder="请输入新脚本名"
            autocomplete="off"
            v-model="newScriptName"
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer" style="text-align: center">
        <el-divider></el-divider>
        <div>
          <el-button
            @click="
              () => {
                (renameVisible = false), (this.newScriptName = '');
              }
            "
            >取 消</el-button
          >
          <el-button
            type="primary"
            @click="
              () => {
                renameScript();
              }
            "
            >确 定</el-button
          >
        </div>
      </span>
    </el-dialog>

    <el-dialog :visible.sync="nameVisible" width="30%">
      <span slot="title" style="text-align: center"
        >创建新脚本
        <el-divider></el-divider>
      </span>
      <el-form label-width="200px">
        <el-form-item label="脚本名：">
          <el-input
            style="width: 50%"
            v-model="newScriptName"
            placeholder="请输入新脚本名"
            autocomplete="off"
          ></el-input>
        </el-form-item>
      </el-form>

      <span slot="footer" class="dialog-footer" style="text-align: center">
        <el-divider></el-divider>
        <div>
          <el-button
            @click="
              () => {
                (this.newScriptName = ''), (nameVisible = false);
              }
            "
            >取 消</el-button
          >
          <el-button
            type="primary"
            @click="
              () => {
                addScript();
              }
            "
            >确 定</el-button
          >
        </div>
      </span>
    </el-dialog>
    <el-dialog
      :visible.sync="triggerVisible"
      width="30%"
      @close="
        () => {
          triggerVisible = false;
          this.$refs['triggerVariableform'].clearValidate();
        }
      "
    >
      <span slot="title" style="text-align: center"
        >变量触发设置
        <el-divider></el-divider>
      </span>
      <el-form
        label-width="200px"
        :model="triggerVariableformData"
        ref="triggerVariableform"
      >
        <el-form-item label="触发变量：">
          <el-cascader
            v-model="triggerVariable"
            placeholder="请选择"
            :options="plcoptions"
            :props="variableprops"
            filterable
            style="width: 60%"
            :filter-method="dataFilter"
          ></el-cascader>
        </el-form-item>
        <el-form-item
          label="扫描周期（ms）："
          prop="scanVariable"
          :rules="[
            { required: true, message: '扫描周期不能为空', trigger: 'blur' },
            { pattern: /^[1-9]\d*$/, message: '请输入正整数' },
          ]"
        >
          <el-input
            type="number"
            v-model="triggerVariableformData.scanVariable"
            style="width: 60%"
          ></el-input>
          <span> *100</span>
        </el-form-item>
      </el-form>

      <span slot="footer" class="dialog-footer" style="text-align: center">
        <el-divider></el-divider>
        <div>
          <el-button
            @click="
              () => {
                this.triggerVisible = false;
                this.$refs['triggerVariableform'].clearValidate();
              }
            "
            >取 消</el-button
          >
          <el-button
            type="primary"
            @click="
              () => {
                saveVariableTrigger(triggerVariable, plcoptions);
              }
            "
            >确 定</el-button
          >
        </div>
      </span>
    </el-dialog>

    <el-dialog :visible.sync="cronVisible" width="30%">
      <span slot="title" style="text-align: center"
        >调度设置
        <el-divider></el-divider>
      </span>
      <corn-view
        :timeCronStr="cronValue"
        @change="saveCronValue"
        @cancel="
          () => {
            cronVisible = false;
          }
        "
      ></corn-view>
      <span slot="footer" class="dialog-footer" style="text-align: center">
      </span>
    </el-dialog>
    <!--代码模板内容详情Dialog -->
    <el-dialog
      destroy-on-close
      :visible.sync="templateContentDialogVisible"
      @close="() => {}"
    >
      <span slot="title"
        >内容详情
        <el-divider></el-divider>
        <span
          style="
            font-weight: bold;
            font-size: 16px;
            color: #333;
            text-align: center;
            width: 100%;
          "
        >
          {{ templateDetail.templateName }}
        </span>
      </span>
      <div>
        <codemirror
          style="height: 600px"
          v-model="templateDetail.templateContent"
          :options="OptionCodeInput"
        ></codemirror>
      </div>
    </el-dialog>
    <!-- 新增、修改代码模板Dialog -->
    <el-dialog
      destroy-on-close
      :visible.sync="templateAddOrEditDialogVisible"
      width="30%"
      @close="
        () => {
          this.templateDialogModel = {
            categoryId: '',
            templateName: '',
            descriptions: '',
          };
        }
      "
    >
      <span slot="title" style="text-align: center"
        >另存为模板
        <el-divider></el-divider>
      </span>
      <el-form
        label-width="200px"
        :model="templateDialogModel"
        ref="templateAddRef"
      >
        <el-form-item
          label="模板名称："
          prop="templateName"
          :rules="[
            {
              required: true,
              message: '模板名称不可为空',
              trigger: ['blur', 'change'],
            },
          ]"
        >
          <el-input
            style="width: 50%"
            v-model="templateDialogModel.templateName"
          ></el-input>
        </el-form-item>
        <el-form-item
          label="模板分类："
          prop="categoryId"
          :rules="[
            {
              required: true,
              message: '模板分类不可为空',
              trigger: ['blur', 'change'],
            },
            {
              validator: (rule, value, callback) => {
                if (value === null) {
                  callback(new Error('模板分类不可为空'));
                } else {
                  callback();
                }
              },
              trigger: ['blur', 'change'],
            },
          ]"
        >
          <el-select
            style="width: 50%"
            v-model="templateDialogModel.categoryId"
          >
            <el-option
              v-for="item in modelData"
              :key="item.Id"
              :label="item.TemplateName"
              :value="item.Id"
            >
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item
          label="说明："
          prop="descriptions"
          :rules="[
            {
              required: true,
              message: '说明不可为空',
              trigger: ['blur', 'change'],
            },
          ]"
        >
          <el-input
            type="textarea"
            :rows="4"
            style="width: 50%"
            v-model="templateDialogModel.descriptions"
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer" style="text-align: center">
        <el-divider></el-divider>
        <div>
          <el-button
            @click="
              () => {
                templateAddOrEditDialogVisible = false;
                //this.classDialogModel.categoryName = '';
              }
            "
            >取 消</el-button
          >
          <el-button
            type="primary"
            @click="confirmSaveTemplateContent(templateDialogModel)"
            >确 定</el-button
          >
        </div>
      </span>
    </el-dialog>
  </div>
</template>

<script>
// #region 覆盖scrollbar样式功能
import "codemirror/addon/scroll/simplescrollbars.css";
import "codemirror/addon/scroll/simplescrollbars";
import "codemirror/addon/display/placeholder.js";
// #endregion

import { codemirror } from "vue-codemirror";
import "codemirror/lib/codemirror.css";
import "codemirror/theme/base16-dark.css";
import "codemirror/mode/clike/clike.js";
import { color } from "echarts/core";
import $http from "../../utils/apiHelper";
import * as $base from "../../utils/js-base64/base64";
import CornView from "./components/CornView.vue";
import axios from "axios";
export default {
  components: { CornView },
  name: "scriptView",
  watch: {
    filterText() {
      if (this.firstRun) {
        this.clickNode(this.findFindFirstSortIndex3(this.treeData));

        setTimeout(() => {
          this.firstRun = false;
        }, 3000); // 等待三秒后执行
      }
      if (!this.firstRun) {
        this.$refs.tree.filter(this.filterText); // 执行节点过滤
        const matchedNode = this.findNodeByLabel(
          this.treeData,
          this.filterText
        );
        if (matchedNode) {
          this.clickNode(matchedNode).then(() => {
            this.$refs.myInput.focus();
            console.log("matchedNode", matchedNode);
            this.$refs.tree.setCurrentKey(matchedNode.Guid); // 设置当前选中节点
          });
        }
      }

      // if (this.filteredData.length > 0) {
      //   this.$refs.tree.setCurrentKey(this.filteredData[0].Guid); // 点击匹配的第一个节点
      // }
    },
    modefilterText(val) {
      this.$refs.codeModelTree.filter(val);
    },
    allCheckedGuids() {
      if (this.allCheckedGuids.length == 0) {
        this.allChecked = false;
        this.isIndeterminate = false;
        return;
      } else if (this.allCheckedGuids.length == this.allGuidsNum) {
        this.allChecked = true;
        this.isIndeterminate = false;
        return;
      } else if (this.allCheckedGuids.length < this.allGuidsNum) {
        this.allChecked = true;
        this.isIndeterminate = true;
        return;
      }
    },
  },
  mounted() {},
  destroyed() {
    this.EditDispose();
  },
  created() {
    this.initEdit();
    this.initPage();
    this.initModel();
    //处理拖拽相关
    //this.inDrop();
  },
  data() {
    return {
      modelOptions: [],
      templateDialogModel: {
        categoryId: "",
        templateName: "",
        descriptions: "",
      },
      templateAddOrEditDialogVisible: false,
      modelBtnIcon: "el-icon-arrow-left",
      OptionCodeInput: {
        // codemirror options
        tabSize: 4,
        mode: "text/x-csharp",
        lineNumbers: true,
        theme: "base16-dark",
        line: true,
        readOnly: "nocursor",
      }, //codeMirror配置项

      templateDetail: "",
      templateContentDialogVisible: false,
      modefilterText: "",
      modelProps: {
        children: "Children",
        label: "TemplateName",
      },
      modelData: [],
      drawer: false,
      isIndeterminate: false,
      allChecked: false,
      filteredData: [], // 存储过滤后的节点数据
      buttonShow: false,
      triggerVariableformData: {
        scanVariable: 0,
      },
      stateTypeOptions: [
        {
          value: -1,
          label: "全选",
        },
        {
          value: 1,
          label: "已发布",
        },
        {
          value: 0,
          label: "未发布",
        },
        {
          value: 2,
          label: "修改待发布",
        },
      ],
      expandedKey: [],
      firstRun: true,
      versionSpan: "",
      ruleNameSpan: "",
      cronValue: "123",
      isPublish: true,
      codeReady: false,
      nowScript: "",
      editable: false,
      triggerVariable: "",
      scanVariable: 0,
      plcoptions: [],
      newScriptName: "",
      seletNode: "",
      cycleSettingForm: {
        interval: "",
      },
      ScanPeriod: "",
      dialogVisible: false,
      cronVisible: false,
      renameVisible: false,
      nameVisible: false,
      triggerVisible: false,
      timeModel: true,
      isedit: "true",
      selectValue: -1,
      filterText: "",
      treeData: [],
      props: {
        label: "DisplayName",
        children: "Children",
      },
      variableprops: {
        multiple: true,
        label: "Name",
        value: "ID",
      },
      scriptMessage: "",
      modeNodeKey: "",
      checkedScripts: [],
      allCheckedGuids: [],
      allGuidsNum: 0,
      fullscreenLoading: false,
      templateLoading: false,
    };
  },
  computed: {},
  methods: {
    getCurrentModel(event) {
      this.modeNodeKey = event.Id;
    },
    // inDrop() {
    //   let dragElem = null;

    //   document.addEventListener("dragstart", function (event) {
    //     dragElem = event.target;
    //     console.log("开始拖拽", event);
    //   });

    //   document.addEventListener("dragover", function (event) {
    //     event.preventDefault();
    //     console.log("结束拖拽", event);
    //   });

    //   document.addEventListener("drop", function (event) {
    //     event.preventDefault();
    //     console.log("drop", event.target);
    //     console.log("drag", dragElem);
    //     // var targetElem = event.target;
    //     // if (targetElem.classList.contains("target")) {
    //     //   targetElem.appendChild(dragElem);
    //     // }
    //   });
    // },
    filterCodeMod(value, data) {
      if (!value) return true;
      return data.TemplateName.indexOf(value) !== -1;
    },
    traverseAndModify(arrynode, fieldName) {
      for (let i = 0; i < arrynode.length; i++) {
        if (arrynode[i][fieldName] !== undefined) {
          arrynode[i][fieldName] = String(arrynode[i][fieldName]);
        }

        if (arrynode[i].Children && arrynode[i].Children.length > 0) {
          arrynode[i].Children.forEach((child) => {
            child[fieldName] = String(child[fieldName]);
          });
        }
      }
    },
    initModel() {
      let param = {
        id: "",
        templateName: "",
        pageSize: 0,
        currentPage: 0,
      };
      //记载脚本模板
      $http.post("/CodeTemplate/GetTemplate", param).then((res) => {
        if (res.Data) {
          this.traverseAndModify(res.Data.pageData, "Id");
          this.modelData = res.Data.pageData;
          this.templateLoading = false;
        }
      });
    },
    initPage() {
      $http(`/Script/GetLineEqScriptInfo?state=${this.selectValue}`).then(
        (res) => {
          if (res.Data) {
            this.treeData = res.Data;
            this.expandedKey = [
              res.Data[0] ? res.Data[0].Guid : 0,
              res.Data[0] ? res.Data[0].Children[0].Guid : 0,
            ];
            this.$nextTick(() => {
              this.$refs.tree.setCurrentKey(
                String(this.treeData[0].Children[0].Guid)
              );
            });
            this.searchAllGuids();
          }
        }
      );
    },
    findNodeByLabel(nodes, label) {
      for (const node of nodes) {
        if (node.Children) {
          const matchedChild = this.findNodeByLabel(node.Children, label);
          if (matchedChild) {
            return matchedChild;
          }
        }
        if (node.DisplayName.includes(label)) {
          return node;
        }
      }
      return null;
    },
    findFindFirstSortIndex3(nodes) {
      for (const node of nodes) {
        if (node.SortIndex == 3) {
          return node;
        }
        if (node.Children) {
          const matchedChild = this.findFindFirstSortIndex3(node.Children);
          if (matchedChild) {
            return matchedChild;
          }
        }
      }
      return null;
    },
    titleIcon(data) {
      switch (data.SortIndex) {
        case 1:
          return "L-line";
        case 2:
          return "L-process";
        case 3:
          return "L-equipment";
        case 4:
          return "L-group";
        case 5:
          return "L-group";
        case 6:
          if (data.State == 0 || data.State == -1) {
            return "L-script  color-grey";
          } else if (data.State == 1) {
            return "L-script  color-green";
          } else if (data.State == 2) {
            return "L-script  color-orange";
          }
      }
    },
    dataFilter(node, val) {
      console.log("val", val, "node", node);
      if (
        !!~node.text.indexOf(val) ||
        !!~node.text.toUpperCase().indexOf(val.toUpperCase())
      ) {
        return true;
      }
    },
    async onContextmenu(event, obj, node) {
      this.seletNode = node.data;
      console.log("node", this.seletNode);
      this.buttonShow = false;
      switch (node.data.SortIndex) {
        case 5:
          this.$contextmenu({
            items: [
              {
                label: "添加规则",
                onClick: () => {
                  this.newScriptName = "";
                  this.nameVisible = true;
                },
              },
            ],
            event,
            x: event.clientX,
            y: event.clientY,
            customClass: "custom-class",
            zIndex: 3,
            minWidth: 230,
          });
          break;
        case 6:
          //刷新脚本内容
          this.buttonShow = true;
          await $http
            .get(`/Script/GetScriptInfo?id=${node.data.StructGuid}`)
            .then((res) => {
              if (res.Data != null) {
                var param = {
                  ...this.seletNode,
                  ...res.Data.EqScript,
                };
                this.seletNode = param;
              }
            });

          if (node.data.FirstLength == 0) {
            this.$contextmenu({
              items: [
                {
                  label: "循环设置",
                  onClick: () => {
                    this.dialogVisible = true;
                    this.cycleSettingForm.interval =
                      this.seletNode.Interval == 0
                        ? ""
                        : this.seletNode.Interval;
                  },
                },
                {
                  label: "重命名",
                  onClick: () => {
                    this.renameVisible = true;
                  },
                },
                { label: "删除规则", onClick: () => this.deleteScript() },
              ],
              event,
              x: event.clientX,
              y: event.clientY,
              customClass: "custom-class",
              zIndex: 3,
              minWidth: 230,
            });
          } else if (node.data.FirstLength == 1) {
            this.$contextmenu({
              items: [
                {
                  label: "调度设置",
                  onClick: () => {
                    console.log("node", this.seletNode);
                    this.cronValue = this.seletNode.CronDesc
                      ? this.seletNode.CronDesc
                      : "";
                    console.log(this.cronValue);

                    this.cronVisible = true;
                    console.log("this.seletNode.Cron", this.seletNode.Cron);
                  },
                },
                {
                  label: "重命名",
                  onClick: () => {
                    this.renameVisible = true;
                  },
                },
                { label: "删除规则", onClick: () => this.deleteScript() },
              ],
              event,
              x: event.clientX,
              y: event.clientY,
              customClass: "custom-class",
              zIndex: 3,
              minWidth: 230,
            });
          } else if (node.data.FirstLength == 2) {
            console.log(node.data);
            this.$contextmenu({
              items: [
                {
                  label: "变量触发设置",
                  onClick: async () => {
                    let response = await $http.get(
                      `/Script/GetScriptVar?eqNo=${node.data.ParentGuid}`
                    );
                    let tst = [];
                    if (response.Data) {
                      response.Data.forEach((a) => {
                        if (a.IsArray) {
                          tst.push({
                            ID: a.ID,
                            Name: a.Name,
                            Alias: a.Alias,
                            children: Array.apply(null, {
                              length: a.ArrayLength,
                            }).map((_, i) => ({ ID: i, Name: i })),
                            StructGuid: node.data.StructGuid,
                          });
                        } else {
                          tst.push({
                            ID: a.ID,
                            Name: a.Name,
                            Alias: a.Alias,
                            StructGuid: node.data.StructGuid,
                          });
                        }
                      });
                    }
                    this.plcoptions = tst;
                    console.log(tst);
                    let res = await $http.get(
                      `/Script/GetVarTriggers?id=${node.data.StructGuid}`
                    );
                    this.triggerVariable = [];
                    if (res.Data) {
                      res.Data.TriggerResDto.forEach((m) => {
                        if (m.isArray) {
                          this.triggerVariable.push([m.id, m.index]);
                        } else {
                          this.triggerVariable.push([m.id]);
                        }
                      });
                    }
                    this.triggerVariableformData.scanVariable =
                      res.Data.ScanPeriod == 0 ? "" : res.Data.ScanPeriod;
                    this.triggerVisible = true;
                  },
                },
                {
                  label: "重命名",
                  onClick: () => {
                    this.renameVisible = true;
                  },
                },
                { label: "删除规则", onClick: () => this.deleteScript() },
              ],
              event,
              x: event.clientX,
              y: event.clientY,
              customClass: "custom-class",
              zIndex: 3,
              minWidth: 230,
            });
          }

          break;
        default:
          break;
      }

      return false;
    },
    bulkPublishing() {
      this.$confirm("此操作将批量发布保存但未发布脚本, 是否继续?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        if (this.checkedScripts.length == 0) {
          this.$message({
            type: "error",
            message: "批量发布的脚本数量为0!",
          });
          return;
        }
        $http
          .post("/Script/BulkPublishScriptContent", this.checkedScripts)
          .then((res) => {
            if (res.Status == 200) {
              this.$message({
                type: "success",
                message: "批量发布成功！!",
              });
              this.getScriptTree();
              this.$refs.tree.setCheckedKeys([]);
            } else {
              this.$message({
                type: "error",
                message: "批量发布失败！!" + res.Message,
              });
            }
          });
      });
    },
    getScriptTree() {
      $http(`/Script/GetLineEqScriptInfo?state=${this.selectValue}`).then(
        (res) => {
          this.treeData = res.Data;
        }
      );
    },
    addScript() {
      var param = {
        Name: this.newScriptName,
        Id: this.seletNode.ParentGuid,
        SortIndex: this.seletNode.SortIndex + 1,
        FirstLength: this.seletNode.FirstLength,
        ParentGuid: this.seletNode.ParentGuid,
      };
      $http.post("/Script/InsetScriptInfo", param).then((res) => {
        if (res.Data != null) {
          this.seletNode.Children.push({
            StructGuid: res.Data.EqScript.ID,
            DisplayName: res.Data.EqScript.Name,
            SortIndex: this.seletNode.SortIndex + 1,
            FirstLength: this.seletNode.FirstLength,
            ParentGuid: res.Data.EqScript.EQId,
            State: -1,
          });
          this.$message({
            type: "success",
            message: "脚本新增成功！",
          });
          this.allGuidsNum = this.allGuidsNum + 1;
          this.nameVisible = false;
          this.newScriptName = "";
        } else {
          this.$message({
            type: "error",
            message: res.Message,
          });
        }
      });
    },
    timeSetting() {},
    renameScript() {
      this.seletNode.Name = this.newScriptName;
      $http.post("/Script/UpdateScriptInfo", this.seletNode).then((res) => {
        if (res.Status == 200) {
          this.seletNode.DisplayName = this.newScriptName;
          // //this.searchOption(this.seletNode, this.treeData,);
          this.searchOption(this.seletNode, this.treeData, {
            StructGuid: res.Data.ID,
            DisplayName: res.Data.Name,
            FirstLength: this.seletNode.FirstLength,
            SortIndex: this.seletNode.SortIndex,
            State: this.seletNode.State,
            ...res.Data,
          });
          this.newScriptName = "";
          this.$message({
            type: "success",
            message: "保存成功!",
          });
          this.renameVisible = false;
          return;
        }

        this.$message({
          type: "error",
          message: res.Message,
        });
      });
    },
    changeInterval(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.seletNode.Interval = this.cycleSettingForm.interval;
          if (this.cycleSettingForm.interval == "") {
            this.$message({
              type: "error",
              message: "间隔时间格式不正确!",
            });
            return;
          }
          $http.post("/Script/UpdateScriptInfo", this.seletNode).then((res) => {
            if (res.Status == 200) {
              this.$message({
                type: "success",
                message: "保存成功!",
              });
              //this.searchOption(this.seletNode, this.treeData,);
              this.searchOption(this.seletNode, this.treeData, {
                StructGuid: res.Data.ID,
                DisplayName: res.Data.Name,
                FirstLength: this.seletNode.FirstLength,
                SortIndex: this.seletNode.SortIndex,
                State: this.seletNode.State,
                ...res.Data,
              });
              this.cycleSettingForm.interval = "";
              this.dialogVisible = false;
            } else {
              this.$message({
                type: "error",
                message: res.Message,
              });
            }
          });
        } else {
          this.$message({
            type: "error",
            message: "间隔时间格式不正确!",
          });
        }
      });
    },
    saveCronValue(a, cronValue) {
      this.seletNode.Cron = cronValue;
      this.seletNode.CronDesc = a;
      $http.post("/Script/UpdateScriptInfo", this.seletNode).then((res) => {
        //this.searchOption(this.seletNode, this.treeData,);
        this.searchOption(this.seletNode, this.treeData, {
          StructGuid: res.Data.ID,
          DisplayName: res.Data.Name,
          FirstLength: this.seletNode.FirstLength,
          SortIndex: this.seletNode.SortIndex,
          State: this.seletNode.State,
          ...res.Data,
        });
        this.$message({
          type: "success",
          message: "保存成功!",
        });
        this.cronValue = "";
        this.cronVisible = false;
      });
    },

    deleteScript() {
      this.$confirm("确定删除该脚本?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          $http
            .get(`/Script/DeleteScriptInfo?id=${this.seletNode.ID}`)
            .then((res) => {
              if (res.Data == true) {
                this.searchOption(this.seletNode, this.treeData);
                this.$message({
                  type: "success",
                  message: "删除成功!",
                });
                this.allGuidsNum = this.allGuidsNum - 1;
                this.versionSpan = "";
                this.ruleNameSpan = "";
                document
                  .getElementById("mainiframe")
                  .contentWindow.VsCode_setValue("");
                this.buttonShow = false;
              } else {
                this.$message({
                  type: "error",
                  message: "删除失败!" + res.Message,
                });
              }
            });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },

    //  递归查找操作的节点，在父节点的children中删除
    searchOption(option, arr, obj) {
      //首先循环arr最外层数据

      for (let s = 0; s < arr.length; s++) {
        //如果匹配到了arr最外层中的我需要删除的数据
        if (arr[s].StructGuid === option.StructGuid) {
          //删除即删除即可
          if (obj) {
            arr.splice(s, 1, obj);
          } else {
            arr.splice(s, 1);
          }
          break;
        } else if (arr[s].Children && arr[s].Children.length > 0) {
          // 递归条件
          this.searchOption(option, arr[s].Children, obj);
        } else {
          continue;
        }
      }
    },
    saveVariableTrigger(trigger, obj) {
      if (obj.length == 0 || trigger.length == 0) {
        this.$message({
          type: "error",
          message: "触发变量不可为空!",
        });
        return;
      }
      this.$refs.triggerVariableform.validate((valid) => {
        if (
          this.triggerVariableformData.scanVariable == 0 ||
          this.triggerVariableformData.scanVariable == ""
        ) {
          this.$message({
            type: "error",
            message: "扫描周期格式不正确!",
          });
          return;
        }
        if (valid) {
          // 表单验证通过，执行提交操作
          // 可以在这里进行其他操作，比如向服务器发送请求
          var param = {
            ID: this.seletNode.StructGuid,
            TriggersList: trigger.map((item) => ({
              id: item[0],
              isArray: item.length > 1,
              index: item.length > 1 ? item[1] : 0,
            })),
            ScanVariable: this.triggerVariableformData.scanVariable,
          };
          $http
            .post("/Script/UpdateVarTriggers", param)
            .then((res) => {
              if (!res.Data) {
                this.triggerVariable = "";
                this.$message({
                  type: "error",
                  message: res.Message,
                });
              } else {
                this.$message({
                  type: "success",
                  message: "触发变量修改成功",
                });
                this.triggerVisible = false;
              }
            })
            .catch((err) => {
              this.$message({
                type: "success",
                message: `${err}`,
              });
            });
        }
      });
    },
    async clickNode(obj, node) {
      this.buttonShow = false;
      this.expandedKey = [obj.Guid];
      this.seletNode = obj;
      if (obj.SortIndex != 3 && obj.SortIndex != 6) return;
      switch (obj.SortIndex) {
        case 3:
          //点击设备初始化编译器
          //初始化代码准备标识
          this.fullscreenLoading = true;
          this.editable = false;
          this.codeReady = false;
          this.$nextTick(function () {
            this.editable = true;
          });

          break;
        case 6:
          //点击脚本发送脚本内容

          //获取当前脚本内容
          this.buttonShow = true;
          if (this.codeReady == true) {
            let info = await $http.get(
              `/Script/GetScriptInfo?id=${this.seletNode.StructGuid}`
            );
            this.isPublish =
              this.seletNode.State == 2 || this.seletNode.State == 0; //是否可以发布
            // if (
            //   JSON.stringify(info.Data.EqScript.ActivatedId) ===
            //   JSON.stringify(info.Data.EqScriptContent.ID)
            // ) {
            //   //是否可以发布
            //   this.isPublish = false;
            // } else {
            //   this.isPublish = true;
            // }
            if (info.Data.EqScriptContent.ScriptContent) {
              document
                .getElementById("mainiframe")
                .contentWindow.VsCode_setValue(
                  info.Data.EqScriptContent.ScriptContent
                );
            } else {
              var code = await document
                .getElementById("mainiframe")
                .contentWindow.VsCode_GetValueByClassName(
                  "testclass",
                  "testfun"
                );
              document
                .getElementById("mainiframe")
                .contentWindow.VsCode_setValue($base.Base64.encodeURL(code));
            }
            this.nowScript = info.Data;
            this.versionSpan =
              "当前发布版本：" +
              (info.Data.EqScriptContent.Description.length > 0
                ? info.Data.EqScriptContent.Description.split(".")[0]
                : "");
            this.ruleNameSpan = info.Data.EqScript.Name;
          }

          break;
        default:
          break;
      }
      // console.log(document.getElementById('mainiframe').contentWindow);
      // console.log(window);
      // console.log(window.frames['mainiframe'].contentWindow);
      // document.getElementById('mainiframe').contentWindow.VsCode_BuildACECode();
    },
    initEdit() {
      window.addEventListener("message", this.trigger);
    },
    EditDispose() {
      window.removeEventListener("message", this.trigger);
    },
    async trigger(event) {
      if (event.data == "editor ready" && this.seletNode.SortIndex == 3) {
        console.log(event.data);
        console.log("seletNode", this.seletNode);
        //获取设备PLC变量转string，转base64

        let res = await $http.get(
          `/Script/GetVarModelDesign?eqNo=${this.seletNode.StructGuid}`
        );
        if (res.Data) {
          document
            .getElementById("mainiframe")
            .contentWindow.VsCode_BuildACECode(
              $base.Base64.encodeURL(JSON.stringify(res.Data))
            );
        }
      } else if (event.data == "code ready") {
        console.log(event.data);

        //准备写入脚本
        this.codeReady = true;
        //document.getElementById('mainiframe').contentWindow.VsCode_BuildACECode();
        this.fullscreenLoading = false;
      }
    },
    saveScript() {
      if (!this.nowScript)
        return this.$message({
          type: "error",
          message: "未选择合适的脚本!",
        });
      if (this.editable) {
        //脚本激活才可以保存
        var ts = document
          .getElementById("mainiframe")
          .contentWindow.VsCode_getValue();
        console.log("获取编辑器值");
        console.log(ts);
        $base.Base64.encodeURL(ts);
        var hash = document
          .getElementById("mainiframe")
          .contentWindow.VsCode_getHash();
        //实际是版本号
        console.log("获取编辑器值哈希值");
        console.log(hash);
        // var param = {
        //   ID: this.nowScript.StructGuid,
        //   HashCode: hash,
        //   ScriptContent: ts,
        // };

        let time = new Date();
        var param = {
          ID: this.nowScript.EqScriptContent.ID,
          ScriptId: this.nowScript.EqScript.ID,
          HashCode: hash,
          Version: this.nowScript.EqScriptContent.Version,
          Description: "",
          Author: 0,
          CreatTime: "2023-04-09T10:08:28.103Z",
          ActivateTime: "2023-04-09T10:08:28.103Z",
          ScriptContent: ts,
          LastExecuteTime: time.toISOString(),
          SubVersion: this.nowScript.EqScriptContent.SubVersion,
          State: 0,
        };
        $http.post("/Script/UpdateScritContent", param).then((res) => {
          if (res.Data) {
            this.nowScript.EqScriptContent = res.Data;
            if (this.seletNode.State != 0 && this.seletNode.State != -1) {
              this.seletNode.State = 2;
            } else {
              this.seletNode.State = 0;
            }
            this.$message({
              type: "success",
              message: "保存脚本成功!",
            });
            this.isPublish = true;
          } else {
            this.isPublish = false;
            this.$message({
              type: "error",
              message: "保存脚本失败!",
            });
          }
        });
      }
    },
    publishContent() {
      this.$confirm("确定发布该任务？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          if (!this.nowScript)
            return this.$message({
              type: "error",
              message: "未选择合适的脚本!",
            });
          var param = {
            ScriptId: this.nowScript.EqScript.ID,
            ScriptContentId: this.nowScript.EqScriptContent.ID,
          };
          $http
            .post(`/Script/PublishScriptContent`, param)
            .then(async (res) => {
              if (res.Data) {
                this.nowScript.EqScriptContent = res.Data;
                this.isPublish = false;
                this.seletNode.State = 1;

                this.$message({
                  type: "success",
                  message: "发布脚本成功!",
                });

                let info = await $http.get(
                  `/Script/GetScriptInfo?id=${this.seletNode.StructGuid}`
                );
                this.versionSpan =
                  "当前发布版本：" +
                  (info.Data.EqScriptContent.Description.length > 0
                    ? info.Data.EqScriptContent.Description.split(".")[0]
                    : "");
                this.ruleNameSpan = info.Data.EqScript.Name;
              } else {
                this.isPublish = true;
                this.$message({
                  type: "error",
                  message: "发布脚本失败!" + res.Message,
                });
              }
            });
        })
        .catch(() => {});
    },

    filterNode(value, data) {
      if (!value) return true;

      return data.DisplayName.indexOf(value) !== -1;
    },

    handleCheckChange(node, checked, indeterminate) {
      const { SortIndex, StructGuid, Children, Guid } = node; // 节点对象包含 SortIndex、StructGuid 和 Children 属性
      if (checked) {
        // 当选中节点时执行的操作
        if (!this.allCheckedGuids.includes(Guid)) {
          this.allCheckedGuids.push(Guid); // 将节点的 StructGuid 添加到 checkedScripts 中
        }

        // 当选中节点时执行的操作
        if (SortIndex === 6 && !this.checkedScripts.includes(StructGuid)) {
          this.checkedScripts.push(StructGuid); // 将节点的 StructGuid 添加到 checkedScripts 中
        }
      } else {
        // 当取消选中节点时执行的操作
        if (this.allCheckedGuids.includes(Guid)) {
          const indexGuid = this.allCheckedGuids.indexOf(Guid);
          this.allCheckedGuids.splice(indexGuid, 1);
        }

        if (SortIndex === 6 && this.checkedScripts.includes(StructGuid)) {
          const index = this.checkedScripts.indexOf(StructGuid);
          this.checkedScripts.splice(index, 1); // 从 checkedScripts 中移除节点的 StructGuid
        }
      }

      // 递归遍历子节点
      if (Children && Children.length > 0) {
        for (let i = 0; i < Children.length; i++) {
          this.handleCheckChange(Children[i], checked, indeterminate);
        }
      }
    },

    allSelect() {
      console.log(this.treeData);
      for (let i = 0; i < this.treeData.length; i++) {
        if (this.allChecked) {
          this.handleCheckChange(this.treeData[i], this.allChecked);
          this.$refs.tree.setCheckedNodes(this.treeData);
        } else {
          this.$refs.tree.setCheckedNodes([]);
        }
      }
    },

    ///查询节点数量 用于用于计算树的全选、半选、不选
    searchAllGuids() {
      for (let i = 0; i < this.treeData.length; i++) {
        if (this.treeData[i].Guid) {
          this.allGuidsNum++;
        }
        // 递归遍历子节点
        if (this.treeData[i].Children && this.treeData[i].Children.length > 0) {
          this.searchAllGuidsHelper(this.treeData[i].Children);
        }
      }
    },

    searchAllGuidsHelper(children) {
      for (let i = 0; i < children.length; i++) {
        if (children[i].Guid) {
          this.allGuidsNum++;
        }
        // 递归遍历子节点
        if (children[i].Children && children[i].Children.length > 0) {
          this.searchAllGuidsHelper(children[i].Children);
        }
      }
    },
    codeInsert(node, data) {
      if (data.Content) {
        let test = data.Content.split(/\r?\n/);
        console.log("切割", test);
        document
          .getElementById("mainiframe")
          .contentWindow.VsCode_AddCodeTextInPositionLine(data.Content);
      } else {
        this.$message.error("该模板的内容为空，请选择其他模板");
      }
    },
    codePreview(node, data) {
      if (data) {
        this.handleTemplateDetail(data);
      }
    },
    /***********代码模板表格操作 */
    handleTemplateDetail(row) {
      this.templateDetail = {
        templateContent: row.Content,
        templateId: row.Id,
        templateName: row.TemplateName,
      };
      this.templateContentDialogVisible = true;
    }, //代码模板详情
    startCodeModel() {
      this.drawer = !this.drawer;
      this.modelBtnIcon =
        this.modelBtnIcon == "el-icon-arrow-left"
          ? "el-icon-arrow-right"
          : "el-icon-arrow-left";
    },
    async confirmSaveTemplateContent(form) {
      this.$refs.templateAddRef.validate((valid) => {
        if (valid) {
          //这里获取的是带命名空间的
          let ts = document
            .getElementById("mainiframe")
            .contentWindow.VsCode_getValue();
          let code = $base.Base64.decode(ts);
          //截取模板

          // var openingBraceCount = 0;
          // var thirdOpeningBraceIndex = -1;
          // var thirdBracketIndex = -1;
          // //开始的第四个{，结尾的第三个}
          // for (var i = 0; i < code.length; i++) {
          //   if (code[i] == "{") {
          //     openingBraceCount++;
          //     if (openingBraceCount === 4) {
          //       thirdOpeningBraceIndex = i;
          //       break;
          //     }
          //   }
          //   if (code[i] == "}") {
          //     openingBraceCount++;
          //     if (openingBraceCount === 3) {
          //       thirdBracketIndex = i;
          //     }
          //   }
          // }
          // var programCode = code.substring(
          //   thirdOpeningBraceIndex + 1,
          //   thirdBracketIndex
          // );
          // console.log(programCode);
          let param = {
            Id: 0,
            CodeTemplateName: form.templateName,
            TemplateClassId: form.categoryId,
            Description: form.descriptions,
            Content: code,
          };

          $http
            .post(`/CodeTemplate/AddCodeTemplate`, param)
            .then((res) => {
              if (res.Data) {
                this.$message({
                  message: "另存为模板代码成功！",
                  type: "success",
                });
                //刷新模板和option
                this.templateAddOrEditDialogVisible = false;
                this.templateLoading = true;
                this.initModel();
              } else {
                this.$message({
                  message: res.Message,
                  type: "error",
                });
              }
            })
            .catch((error) => {
              this.$message({
                type: "error",
                message: `另存为模板代码失败！${error}`,
              });
            });
        }
      });
    },
  },
};
</script>
<style scoped>
.blue-square {
  margin: 4px;
  width: 14px; /* 设置正方形的宽度 */
  height: 12px; /* 设置正方形的高度 */
  background-color: #9fd9d5; /* 设置背景颜色为蓝色 */
  border: 2px solid black;
  display: inline-block;
  border-radius: 4px; /* 设置圆角半径 */
  vertical-align: text-top;
}
#my-model.el-tree-node__content {
  margin-top: 5vh;
}
.drawer {
  overflow: auto;
  padding: 15px;
  margin: 1.5px;
  border: 1px solid #dcdfe6;
  min-width: 12vw;
  max-width: 15vw;
  height: 95%;
  display: flex;
  flex-direction: column;
}
.model-tree {
  flex: 1;
  margin-top: 15px;
}
.color-green {
  color: #62ff67;
}
.color-orange {
  color: #ff8c00;
}
.color-grey {
  color: grey;
}
.el-tree-node.is-expanded > .el-tree-node__children {
  display: inline;
}
.iframe {
  flex: 1;
  height: 100%;
}
.modelbtn {
  margin: 6px;
  width: 1vw;
  height: 4vh;
}

.fade-leave,
.fade-enter-to {
  opacity: 1;
}
.fade-leave-active,
.fade-enter-active {
  transition: all 0.5s;
}
.fade-leave-to,
.fade-enter {
  opacity: 0;
}
.custom-tree-node {
  width: 25vw;
}
.span-div {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}

::v-deep .CodeMirror {
  height: 600px;
}

div[draggable="true"] {
  cursor: move;
}

div[draggable="true"]:active {
  opacity: 0.5;
}
</style>
